package org.summerframework.core.base.service.impl;


import org.summerframework.core.base.dao.BaseQueryDAO;
import org.summerframework.core.base.dto.BaseDO;
import org.summerframework.core.base.dto.BaseDTO;
import org.summerframework.core.base.service.BaseQueryService;
import org.summerframework.core.exception.WebException;
import org.summerframework.core.page.PageResult;
import org.summerframework.core.page.PaginationHelper;
import org.summerframework.core.page.PaginationQuery;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Collections;
import java.util.List;

/**
 * 添加,自动完成
 * <p>
 * {@link AbstractBaseService}
 * {@link #selectByQuery(PaginationQuery)}
 * {@link #selectCountByQuery(PaginationQuery)}
 *
 * @param <T> 对应的DTO对象
 * @param <Q> 对应的Query对象
 * @author 石超
 * @version 1.0.0
 */
public abstract class AbstractBaseQueryService<DAO extends BaseQueryDAO<D, Q>, T extends BaseDTO, Q extends PaginationQuery, D extends BaseDO>
        extends AbstractBaseService<DAO, T, D> implements BaseQueryService<T, Q> {


    @Override
    public Integer selectCountByQuery(Q query) throws WebException {
        return getDAO().selectCountByQuery(constructQuery(query));
    }

    @Override
    public List<T> selectByQuery(Q query) throws WebException {
        return fromDO2DTO(getDAO().selectByQuery(constructQuery(query)));
    }

    @Override
    public PageResult<T> selectPageResultByQuery(Q query) throws WebException {
        Integer count = selectCountByQuery(constructQuery(query));
        if (count == null || count.equals(0)) {
            return PaginationHelper.fetchPage(0, query, Collections.emptyList());
        } else {
            return PaginationHelper.fetchPage(count, query, selectByQuery(constructQuery(query)));
        }
    }

    @Override
    public T selectOne(Q query) throws WebException {
        query.setPageSize(1);
        List<T> ts = selectByQuery(constructQuery(query));
        return CollectionUtils.isNotEmpty(ts) ? ts.get(0) : null;
    }

    protected final Q constructQuery(Q query) {
        if (query.isConstruct()) {
            return query;
        }

        query.setConstruct(true);
        return doConstructQuery(query);
    }

    protected Q doConstructQuery(Q query) {
        return query;
    }
}
